package tcp

import (
	"bufio"
	"context"
	"go_redis_service/lib/logger"
	"go_redis_service/lib/sync/atomic"
	"go_redis_service/lib/sync/wait"
	"io"
	"net"
	"sync"

	"time"
)

// EchoHandler
// @Description: conn的总管家
type EchoHandler struct {
	activeConn sync.Map
	closing    atomic.Boolean
}

// NewHandler
// @Description: 创建管家
// @return *EchoHandler
func NewHandler() *EchoHandler {
	return &EchoHandler{}
}

// EchoClient
// @Description: 每个连接的处理Client
type EchoClient struct {
	Conn    net.Conn
	Waiting wait.Wait
}

func (c *EchoClient) Close() error {
	c.Waiting.WaitWithTimeout(time.Second * 10)
	c.Conn.Close()
	return nil
}

// Handle
// @Description: 处理连接
// @receiver h
// @param ctx
// @param conn
func (h *EchoHandler) Handle(ctx context.Context, conn net.Conn) {
	// 检测是否正在关闭
	if h.closing.Get() {
		_ = conn.Close()
	}
	client := &EchoClient{
		Conn: conn,
	}
	h.activeConn.Store(client, struct{}{})

	// 读文件
	reader := bufio.NewReader(conn)
	for true {
		message, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				logger.Info("connection close")
				h.activeConn.Delete(client)
			} else {
				logger.Warn(err)
			}
			return
		}
		//logger.Info(fmt.Sprintf("accept message %s", string(message)))
		client.Waiting.Add(1)
		b := []byte(message)
		_, _ = conn.Write(b)
		client.Waiting.Done()
	}
}

func (h *EchoHandler) Close() error {
	logger.Info("handler shutting down...")
	h.closing.Set(true)
	h.activeConn.Range(func(key, value any) bool {
		client := key.(*EchoClient)
		_ = client.Close()
		return true
	})
	return nil
}
